www.gusucode.com > VC++ douglas道格拉斯算法示例-源码程序 > VC++ douglas道格拉斯算法示例-源码程序/code/myAPI.cpp

    //Download by http://www.NewXing.com
#include "stdafx.h" 
#include "myAPI.h"

#include <math.h>

void WINAPI DouglasPeuckerDataCompress(POINT* orgPoint,int nPt, CUIntArray& aPtNum,double tolerance)
{
	CUIntArray NumPoint;
	aPtNum.RemoveAll();	
	ColInfoArray aStack;
	COLINFO from_to;
	
	double deepth;
	int nSt,nEd; 
	int i,j,tempNum;
	nSt = 0;
	nEd = nPt-1;
	NumPoint.Add(nSt);
	NumPoint.Add(nEd);
	BOOL flag = TRUE;
	CPoint hhh;
	do
	{		
		tempNum = GetMaxArcLength(orgPoint,nPt,nSt,nEd,deepth);
		if(deepth>tolerance)
		{
			NumPoint.Add(tempNum);
			from_to.from = tempNum;
			from_to.to = nEd;
			aStack.Add(from_to);
			nEd = tempNum;
		}
		else
		{
			int numStack = aStack.GetSize();
			if(numStack==0)
				flag = FALSE;
			else
			{
				from_to = aStack.GetAt(numStack-1);
				nSt = from_to.from;
				nEd = from_to.to;
				aStack.RemoveAt(numStack-1);
			}
		}
		
	}while(flag);
	
	int numPt = NumPoint.GetSize();	
	int minNum,k;
	for(j=0;j<numPt;j++)
	{
		minNum = NumPoint.GetAt(0);
		k = 0;
		for(i=1;i<NumPoint.GetSize();i++)
		{
			if(minNum>(int)NumPoint.GetAt(i))
			{
				minNum = NumPoint.GetAt(i);
				k = i;
			}
		}
		aPtNum.Add(minNum);
		if (k<NumPoint.GetSize())
		{
			NumPoint.RemoveAt(k);
		}
		
	}
}


int WINAPI GetMaxArcLength(POINT* point,int nPt,int nStart,int nEnd,double& maxLength)
{
	int i,numPoint;
	double dee = 0;
	maxLength = 0;
	numPoint = nStart;
	POINT pt,LinePt1,LinePt2;
// 	double dis;
	
	for(i=nStart+1;i<nEnd;i++)
	{
		//double a,b,c;
		//a = (double)point[nEnd].y-(double)point[nStart].y;
		//b = (double)point[nStart].x-(double)point[nEnd].x;
		//c = -b*((double)point[nStart].y)-a*((double)point[nStart].x);
		//dee = fabs(a*((double)point[i].x)+b*((double)point[i].y)+c)/sqrt(a*a+b*b);
        
		//==  Modified by Ai, August 14, 2003 , HongKong
		pt=point[i]; LinePt1=point[nEnd];  LinePt2=point[nStart];
        dee=DistancePointToLine(pt,LinePt1,LinePt2);
		
		if(maxLength<dee)
		{
			maxLength = dee;
			numPoint = i;
		}
	}
	return numPoint;
}


double WINAPI DistancePointToLine(POINT pt,POINT LinePt1,POINT LinePt2)
{
	INTERSECT inter;
	fLINE     line;
	DPOINT    Apt;
	Apt.x=(float)pt.x;
	Apt.y=(float)pt.y;
	line.sx=(float)LinePt1.x;
	line.sy=(float)LinePt1.y;
	line.ex=(float)LinePt2.x;
	line.ey=(float)LinePt2.y;
	DisPtToLine(&inter,Apt,line);
	if(inter.In) return (double)inter.Dis; 
	else
	{
		double dis1 = DistanceBetweenTwoPoints(pt,LinePt1);
		double dis2 = DistanceBetweenTwoPoints(pt,LinePt2);
		return (dis1 < dis2)?dis1:dis2;
	}
}

double WINAPI DistanceBetweenTwoPoints(DPOINT pt1,DPOINT pt2)
{
	double A = pt1.x-pt2.x;
	double B = pt1.y-pt2.y;
	return sqrt(A*A+B*B);
}

void WINAPI DisPtToLine(INTERSECT* Inters,DPOINT Apt,fLINE line)
{ 
	float	A,B,C;
	DPOINT	pt;

	A=line.sy-line.ey;
	B=line.ex-line.sx;
	if(fabs(A)<0.00001 && fabs(B)<0.00001)
	{ Inters->pt.x=line.sx;
	Inters->pt.y=line.sy;
	Inters->In=TRUE;
	Inters->Dis=DistanceBetweenTwoPoints(Apt,Inters->pt);
	return;
	}

	C=(line.sx-line.ex)*line.sy+(line.ey-line.sy)*line.sx;
	double dis = A*Apt.x+B*Apt.y+C;
	Inters->Dis=(float)fabs(dis)/(float)sqrt(A*A+B*B);

	pt.x=(B*B*Apt.x-A*B*Apt.y-A*C)/(A*A+B*B);
	pt.y=(A*A*Apt.y-A*B*Apt.x-B*C)/(A*A+B*B);

	Inters->pt.x=pt.x;
	Inters->pt.y=pt.y;
	if((pt.x>min(line.sx,line.ex) && pt.x<max(line.sx,line.ex))||
		  (pt.y>min(line.sy,line.ey) && pt.y<max(line.sy,line.ey)))
		  Inters->In=TRUE;
	else
	Inters->In=FALSE;
	return;
}


double WINAPI DistanceBetweenTwoPoints(POINT pt1,POINT pt2)
{
	double A = (double)pt1.x-(double)pt2.x;
	double B = (double)pt1.y-(double)pt2.y;
	return sqrt(A*A+B*B);
}